<template>
    <div>
        <div v-if="!isRead" class="edu-opertion-bar">
            <div class="float-left"></div>
            <div class="float-right">
                <el-button
                    v-if="dataType === '1'"
                    type="primary"
                    @click="addCourseCategory"
                >{{ $t("common.btn.add") }}</el-button>
            </div>
        </div>
        <div v-if="next" class="tip-message">{{ tip }}</div>
        <el-table
            :data="processedData"
            :span-method="arraySpanMethod"
            :summary-method="getSummaries"
            border
        >
            <el-table-column prop="name" label="课程类别" align="center" />
            <el-table-column label="子类别" align="center">
                <template slot-scope="props">{{ props.row.subName }}</template>
            </el-table-column>
            <el-table-column prop="score" label="学分" width="100px" align="center">
                <template slot-scope="props">
                    <el-input
                        v-if="!isRead"
                        v-model="props.row.score"
                        type="text"
                        @focus="focusInput(props.row)"
                        @blur="blurInput(props.row)"
                    />
                    <span v-if="isRead">{{ props.row.score }}</span>
                </template>
            </el-table-column>
            <el-table-column prop="percent" label="百分比%" align="center">
                <template v-if="props.row.labelId !== ''" slot-scope="props">
                    {{
                    getPercent(props.row)
                    }}
                </template>
            </el-table-column>
            <el-table-column v-if="!isRead && operateBlock" label width="140px">
                <template v-if="props.row.labelId !== ''" slot-scope="props">
                    <el-button type="text" size="mini" @click="removeRow(props.row)">删除</el-button>
                    <el-button
                        v-if="
                            !!props.row.subName &&
                                props.row.subLength !== 1 &&
                                props.row.index !== 1
                        "
                        type="text"
                        size="mini"
                        @click="moveUp(props.row)"
                    >上移</el-button>
                    <el-button
                        v-if="
                            !!props.row.subName &&
                                props.row.subLength !== 1 &&
                                props.row.index != props.row.subLength
                        "
                        type="text"
                        size="mini"
                        @click="moveDown(props.row)"
                    >下移</el-button>
                </template>
            </el-table-column>
            <el-table-column v-if="!isRead && operateBlock" label width="140px">
                <template v-if="props.row.labelId !== ''" slot-scope="props">
                    <el-button
                        v-if="props.row.pindex !== 1"
                        type="text"
                        size="mini"
                        @click="moveUp(props.row, 1)"
                    >上移</el-button>
                    <el-button
                        v-if="topCategoryLength != props.row.pindex"
                        type="text"
                        size="mini"
                        @click="moveDown(props.row, 1)"
                    >下移</el-button>
                </template>
            </el-table-column>
        </el-table>
        <el-row v-if="next" class="pd-12px float-right" style="padding-right: 0;">
            <el-col :span="24">
                <el-button size="medium" @click="backStep">上一步</el-button>
                <el-button v-if="!isRead" size="medium" @click="submit(null)">保存</el-button>
                <el-button size="medium" type="primary" @click="nextStep">下一步</el-button>
            </el-col>
        </el-row>

        <el-dialog
            :visible.sync="addCategoryVisible"
            :before-close="handleClose"
            :title="$t('culture.template.addCourseCategory')"
            width="34%"
            :close-on-click-modal="false"
            :close-on-press-escape="false"
        >
            <el-card shadow="never" body-style="padding: 24px;">
                <el-table
                    ref="categoryTable"
                    :span-method="arraySpanMethod"
                    :data="courseCheckedData"
                    border
                    @selection-change="handleSelectionChange"
                >
                    <el-table-column prop="name" label="课程类别" align="center" />
                    <el-table-column label="子类别">
                        <template slot-scope="props">
                            {{
                            props.row.subName
                            }}
                        </template>
                    </el-table-column>
                    <el-table-column type="selection" width="55" />
                </el-table>
            </el-card>
            <span slot="footer" class="dialog-footer">
                <el-button @click="addCategoryVisible = false">取 消</el-button>
                <el-button type="primary" @click="submitCourseCategory">确 定</el-button>
            </span>
        </el-dialog>
    </div>
</template>
<script>
import {
    saveCourseCategoryForm,
    getCourseCategoryFormById,
    coursesLabelTreeList,
    batchSaveCultureRule,
    findCheckedCultureLabelList
} from "common/src/api/courseTemplate";
import { deleteCultureRule } from "common/src/api/culture/cultureSchemeRule";
import UTILS from "common/src/utils/utils";
import { queryDic } from "common/src/api/dictionary";
export default {
    name: "course-category-form",
    props: {
        next: {
            type: Function,
            default: null
        },
        templateIdOrigin: {
            //此id是原始模板id,用于本页课程学分和原始模板分数校验使用，仅使用于此，与其他无关
            type: Number,
            default: null
        },
        templateId: {
            type: Number,
            default: null
        },
        isRead: {
            type: Boolean,
            default: false
        },
        dataType: {
            type: String,
            default: "1" // 1为模板，2为方案
        }
    },
    data() {
        return {
            tip:
                '"课程类别"会自动关联到相应的学生，请教务员填写每个课程类别的最低学分要求。',
            resCategories: [], // 缓存返回的分类数据
            courseCategories: [], // 原始数据
            processedData: [], // 转换后数据
            courseCheckedData: [], // 课程选择
            courseCheckeds: [],
            courseOriginData: [], //此数据是模板课程的原始数据，仅用于本页学分校验
            topCategoryLength: 0,
            addCategoryVisible: false,
            queryForm: {
                trainingLevel: ""
            },
            options: {
                trainingLevel: [],
                labelTypes: []
            },
            tree: {
                data: [],
                defaultProps: {
                    children: "childs",
                    label: "label"
                },
                checkedList: []
            },
            operateBlock: false
        };
    },
    created() {
        this.getCourseCategory();
        this.initOptions();
        const roleInfo = JSON.parse(localStorage.getItem("user"));
        const rdx =
            roleInfo &&
            roleInfo.innerRoles.findIndex(
                e => e * 1 == roleInfo.currentRole * 1
            );
        //查看当前登陆角色权限是否属于本人角色权限
        if (rdx > -1) {
            //查看是否有校管理员权限
            if (
                roleInfo &&
                roleInfo.innerRoles.findIndex(e => e * 1 == 1) > -1
            ) {
                //找到校管理员角色信息,操作模块显示
                this.operateBlock = true;
            } else {
                this.operateBlock = false;
            }
        } else {
            this.operateBlock = false;
        }
    },
    methods: {
        initOptions() {
            const data = {
                lang: this.$store.getters.language || "cn",
                type: "allChild",
                keys: ["X_PYCC"]
            };
            queryDic(data).then(res => {
                if (res.code === 200) {
                    UTILS.fillSelect(
                        {
                            trainingLevel: "X_PYCC"
                        },
                        res.data,
                        this.options
                    );
                }
            });
            //获取原始课程数据
            if(this.templateIdOrigin){
                getCourseCategoryFormById(this.templateIdOrigin, "1")
                    .then(res => {
                        if (res.code === 200) {
                            this.courseOriginData =
                                (res.data.cultureRuleList.length > 0) ?
                                res.data.cultureRuleList : [];
                        }
                    })
                    .catch(err => {
                        console.log(err);
                    });
            }
        },
        // 输入框获取焦距
        focusInput(row) {
            if (row.score === 0) {
                row.score = "";
            }
        },
        // 输入框失去焦距
        blurInput(row) {
            if (row.score.trim() === "") {
                row.score = 0;
            }
            const value = Number(row.score);
            if (isNaN(value)) {
                row.score = 0;
            } else if (value < 0) {
                row.score = Math.abs(row.score);
            }
            // row.score = Math.floor(row.score); //处理小数
        },
        scopeCheck(callback) {
            const _this = this;
            try {
                _this.processedData.forEach(e => {
                    const checkScore = _this.courseOriginData.find(
                        c => c.labelId * 1 == e.labelId * 1
                    );
                    if (checkScore) {
                        if (e.score * 1 < checkScore.credit * 1) {
                            _this.prompt("single", e.name);
                            throw "jumpout";
                        }
                    }
                });
                const totalScore = _this.processedData
                    .map(item => item.score)
                    .reduce(function(total, num) {
                        return parseInt(total) + parseInt(num);
                    }, 0);
                const isTotalMax =
                    (_this.processedData.length > 0
                        ? _this.processedData[_this.processedData.length - 1]
                              .score
                        : 0) *
                        1 >=
                    totalScore -
                        (_this.processedData.length > 0
                            ? _this.processedData[
                                  _this.processedData.length - 1
                              ].score
                            : 0) *
                            1;
                callback(isTotalMax);
            } catch (e) {
                console.log(e);
            }
        },
        prompt(type = "total", courseName) {
            if (type == "total") {
                this.$message({
                    type: "warning",
                    message: this.$t("culture.courseCategory.totalScoreLimit")
                });
            } else {
                this.$message({
                    type: "warning",
                    message: `${courseName}${this.$t(
                        "culture.courseCategory.singleScoreLimit"
                    )}`
                });
            }
        },
        // 课程类型去重
        setData(parent, data) {
            let obj = {};
            let array = parent.reduce((cur, next) => {
                obj[next.pid] ? "" : (obj[next.pid] = true && cur.push(next));
                return cur;
            }, []);
            this.resCategories.forEach(item => {
                array.forEach(child => {
                    if (item.labelId == child.pid) {
                        data.cultureRuleList.unshift({
                            id: item.id,
                            labelId: item.labelId,
                            credit: item.credit,
                            level: child.plevel,
                            type: this.dataType,
                            orderNo: child.pindex
                        });
                    }
                });
            });
        },
        submit(callback) {
            if (this.processedData.length === 0) {
                this.$message({
                    type: "warning",
                    message: this.$t("culture.courseCategory.tipNoData")
                });
                return;
            }
            const data = {
                id: this.templateId,
                cultureRuleList: []
            };
            this.scopeCheck(state => {
                let parent = [];
                if (!state) {
                    this.prompt();
                } else {
                    this.processedData.forEach(row => {
                        data.cultureRuleList.push({
                            id: row.id,
                            labelId: row.labelId,
                            credit: row.score,
                            level: row.level,
                            type: this.dataType,
                            orderNo: row.index
                        });
                        if (row.pid) {
                            parent.push(row);
                        }
                    });
                    this.setData(parent, data);
                    saveCourseCategoryForm(data).then(response => {
                        if (response.code === 200) {
                            this.$message({
                                type: "success",
                                message: this.$t(
                                    "culture.courseCategory.saveSuccess"
                                )
                            });
                            if (callback) {
                                callback();
                            }
                        }
                    });
                }
            });
        },
        // 上一步
        backStep() {
            if (this.next) {
                this.next(-1);
            }
        },
        // 下一步
        nextStep() {
            this.scopeCheck(state => {
                if (!state) {
                    this.prompt();
                } else {
                    if (this.isRead) {
                        if (this.next) {
                            this.next();
                        }
                    } else {
                        this.submit(() => {
                            if (this.next) {
                                this.next();
                            }
                        });
                    }
                }
            });
        },
        // 获取百分比
        getPercent(row) {
            const scoresArr = this.processedData.map(p => p.score);
            let totalScore = scoresArr.reduce((prev, curr, index) => {
                const value = Number(curr);
                if (!isNaN(value) && scoresArr.length !== index + 1) {
                    return Number(prev) + Number(curr);
                } else {
                    return Number(prev);
                }
            }, 0);

            if (isNaN(totalScore) || totalScore === 0) {
                totalScore = 1;
            }
            return (
                (parseFloat(row.score / totalScore).toFixed(4) * 100).toFixed(
                    2
                ) + "%"
            );
        },
        // 合计
        getSummaries(param) {
            const { columns, data } = param;
            const sums = [];
            columns.forEach((column, index) => {
                if (index === 0) {
                    sums[index] = "总计";
                    return;
                }
                if (index === 1 || index === 3) {
                    sums[index] = "";
                    return;
                }
                const values = data.map(item => Number(item[column.property]));
                sums[index] = values.reduce((prev, curr) => {
                    const value = Number(curr);
                    if (!isNaN(value)) {
                        return prev + curr;
                    } else {
                        return prev;
                    }
                }, 0);
            });
            return sums;
        },
        // 计算合并单元格
        arraySpanMethod({ row, column, rowIndex, columnIndex }) {
            if (columnIndex === 0) {
                if (row.isMixed) {
                    if (row.isFirst) {
                        return {
                            rowspan: row.subLength,
                            colspan: 1
                        };
                    } else {
                        return {
                            rowspan: 0,
                            colspan: 0
                        };
                    }
                }
            }
            if (columnIndex === 5) {
                if (row.isMixed) {
                    if (row.isFirst) {
                        return {
                            rowspan: row.subLength,
                            colspan: 1
                        };
                    } else {
                        return {
                            rowspan: 0,
                            colspan: 0
                        };
                    }
                }
            }
        },
        // 获取模板详情/培养方案详情课程分类
        getCourseCategory() {
            getCourseCategoryFormById(this.templateId, this.dataType).then(
                response => {
                    if (response.code === 200) {
                        if (
                            response.data.cultureRuleList &&
                            response.data.cultureRuleList.length > 0
                        ) {
                            this.resCategories = response.data.cultureRuleList;
                            this.__fromatData(response.data.cultureRuleList);
                        }
                    }
                }
            );
        },
        // 转换原始数据为视图数据
        __convert() {
            const largeCategories = this.courseCategories.filter(
                c => c.pid === "0"
            );
            const result = [];
            largeCategories.forEach(large => {
                const smallCategories = this.courseCategories.filter(
                    small => small.pid === large.labelId
                );
                // 是否存在子分类
                if (smallCategories.length > 0) {
                    let isFirst = true;
                    smallCategories.forEach(small => {
                        result.push({
                            id: small.id,
                            labelId: small.labelId,
                            name: large.name,
                            score: small.score,
                            subName: small.name,
                            level: small.level,
                            pid: large.labelId,
                            plevel: large.level,
                            isFirst: isFirst,
                            labelType: small.labelType,
                            subLength: smallCategories.length,
                            orderNo: small.orderNo,
                            index: small.index,
                            pindex: large.index,
                            isMixed: true // 包含子分类
                        });
                        isFirst = false;
                    });
                } else {
                    result.push({
                        id: large.id,
                        labelId: large.labelId,
                        level: large.level,
                        name: large.name,
                        score: large.score,
                        orderNo: large.orderNo,
                        index: large.index,
                        pindex: large.index,
                        labelType: large.labelType,
                        subName: ""
                    });
                }
            });
            this.processedData = result;
            console.log(result);
        },
        // 格式化课程分类数据
        __fromatData(data) {
            this.topCategoryLength = data.filter(o => o.level === "1").length;
            this.courseCategories.length = 0;
            data[0].level = 999;
            data = _.sortBy(data, ["level", "index", "orderNo"]);
            if (data && data.length > 0) {
                data.forEach(row => {
                    if (row.labelId) {
                        this.courseCategories.push({
                            id: row.id,
                            labelId: row.labelId,
                            level: row.level,
                            name: row.label,
                            pid: row.parentId,
                            score: row.credit,
                            orderNo: row.orderNo,
                            labelType: row.labelType,
                            index: row.index
                        });
                    } else {
                        this.courseCategories.push({
                            id: row.id,
                            labelId: "",
                            name: "总学分",
                            pid: "0",
                            score: row.credit,
                            orderNo: row.orderNo,
                            index: row.index
                        });
                    }
                });
            } else if (data) {
                data.coursesLabelList.forEach(row => {
                    this.courseCategories.push({
                        id: row.id,
                        labelId: row.labelId,
                        name: row.label,
                        pid: row.parentId,
                        score: row.credit,
                        orderNo: row.orderNo,
                        labelType: row.labelType,
                        index: row.index
                    });
                });
            }
            this.__convert();
        },

        // 获取所有课程分类
        getAllCourseCategorys() {
            const that = this;
            const params = {
                templateId: this.templateId
            };
            const data = {
                taringingId: this.templateId,
                type: this.dataType
            };
            const checkedIndexs = [];
            let fn = (list = []) => {
                let result;
                result = list
                    .sort(function(item1, item2) {
                        return item1.label.localeCompare(item2.label, "zh-CN");
                    })
                    .reverse();
                let index = result.findIndex(e => e.label == "补修课");
                if (index > 0) {
                    let obj = result[index];
                    result.splice(index, 1);
                    return [...result, ...[obj]];
                } else {
                    return result;
                }
            };
            coursesLabelTreeList(params).then(res => {
                if (res && res.code === 200) {
                    this.courseCheckedData = this.__getCategoryList(
                        fn(res.data)
                    );
                    findCheckedCultureLabelList(data).then(res => {
                        if (res.data && res.code === 200) {
                            _.forEach(_.map(res.data, "labelId"), item => {
                                checkedIndexs.push(
                                    _.findIndex(that.courseCheckedData, o => {
                                        return o.id === item;
                                    })
                                );
                                let checkedData = _.find(that.processedData, {
                                    labelId: item.toString()
                                });
                                let needCheckedData = _.find(
                                    that.courseCheckedData,
                                    {
                                        id: item
                                    }
                                );
                            });
                            _.forEach(checkedIndexs, index => {
                                if (index !== -1) {
                                    this.$refs.categoryTable.toggleRowSelection(
                                        that.courseCheckedData[index]
                                    );
                                }
                            });
                        }
                    });
                }
            });
        },
        __getCategoryList(data) {
            const that = this;
            const returnArr = [];
            _.forEach(data, large => {
                // 是否存在子分类
                if (large.childs) {
                    let isFirst = true;
                    large.childs.forEach(small => {
                        returnArr.push({
                            id: small.id,
                            name: small.parentName,
                            subName: small.label,
                            level: small.level,
                            pid: large.id,
                            plevel: small.level - 1,
                            isFirst: isFirst,
                            subLength: large.childs.length,
                            isMixed: true // 包含子分类
                        });
                        isFirst = false;
                    });
                } else {
                    returnArr.push({
                        id: large.id,
                        level: large.level,
                        name: large.label,
                        subName: ""
                    });
                }
                if (large.childs) {
                    returnArr.concat(that.__getCategoryList(large.childs));
                }
            });
            return returnArr;
        },
        addCourseCategory() {
            this.addCategoryVisible = true;
            this.getAllCourseCategorys();
        },
        __getCheckedNodes() {
            if (this.courseCheckeds.length == 0) {
                this.$message({ type: "warning", message: "请选择课程类别" });
                return;
            }
            const data = {
                id: this.templateId,
                cultureRuleList: this.courseCheckeds
            };
            batchSaveCultureRule(data).then(res => {
                if (res.code === 200) {
                    this.getCourseCategory();
                    this.addCategoryVisible = false;
                }
            });
        },
        submitCourseCategory() {
            //   this.addCategoryVisible = false;
            this.__getCheckedNodes();
        },
        removeRow(row) {
            const params = {
                id: row.id
            };
            this.$confirm(
                this.$t("common.tips.beSure"),
                this.$t("common.text.info"),
                {
                    confirmButtonText: this.$t("common.btn.confirm"),
                    cancelButtonText: this.$t("common.btn.cancel"),
                    type: "warning"
                }
            ).then(() => {
                let isOnlySubCategory = false;
                if (row.level == 2) {
                    isOnlySubCategory =
                        this.resCategories.filter(e => e.parentId === row.pid)
                            .length === 1;
                }
                deleteCultureRule(params).then(res => {
                    if (res.code === 200) {
                        if (isOnlySubCategory) {
                            //删除父类
                            let parentCategory = this.resCategories.find(
                                e => e.labelId === row.pid
                            );
                            if (parentCategory) {
                                deleteCultureRule({
                                    id: parentCategory.id
                                }).then(result => {
                                    if (result.code === 200) {
                                        this.getCourseCategory();
                                        this.$message({
                                            type: "success",
                                            message: this.$t(
                                                "common.tips.deleteSuccess"
                                            )
                                        });
                                    }
                                });
                            }
                        } else {
                            this.getCourseCategory();
                            this.$message({
                                type: "success",
                                message: this.$t("common.tips.deleteSuccess")
                            });
                        }
                    }
                });
            });
        },
        moveUp(row, flag) {
            let currentItemIndex = -1;
            let targetItemIndex = -1;
            if (flag) {
                const pid = row.pid ? row.pid : row.labelId;
                currentItemIndex = _.findIndex(this.resCategories, {
                    labelId: pid
                });
                targetItemIndex = _.findIndex(this.resCategories, {
                    level: this.resCategories[currentItemIndex].level,
                    index:
                        parseInt(this.resCategories[currentItemIndex].index) - 1
                });
            } else {
                currentItemIndex = _.findIndex(this.resCategories, {
                    labelId: row.labelId
                });
                targetItemIndex = _.findIndex(this.resCategories, {
                    parentId: this.resCategories[currentItemIndex].parentId,
                    level: this.resCategories[currentItemIndex].level,
                    index:
                        parseInt(this.resCategories[currentItemIndex].index) - 1
                });
            }
            if (currentItemIndex !== -1 && targetItemIndex !== -1) {
                this.resCategories[targetItemIndex].index =
                    parseInt(this.resCategories[targetItemIndex].index) + 1;
                this.resCategories[currentItemIndex].index =
                    parseInt(this.resCategories[currentItemIndex].index) - 1;
                this.__fromatData(this.resCategories);
            }
        },
        moveDown(row, flag) {
            let currentItemIndex = -1;
            let targetItemIndex = -1;
            if (flag) {
                const pid = row.pid ? row.pid : row.labelId;
                currentItemIndex = _.findIndex(this.resCategories, {
                    labelId: pid
                });
                targetItemIndex = _.findIndex(this.resCategories, {
                    level: this.resCategories[currentItemIndex].level,
                    index:
                        parseInt(this.resCategories[currentItemIndex].index) + 1
                });
            } else {
                currentItemIndex = _.findIndex(this.resCategories, {
                    labelId: row.labelId
                });
                targetItemIndex = _.findIndex(this.resCategories, {
                    parentId: this.resCategories[currentItemIndex].parentId,
                    level: this.resCategories[currentItemIndex].level,
                    index:
                        parseInt(this.resCategories[currentItemIndex].index) + 1
                });
            }
            if (currentItemIndex !== -1 && targetItemIndex !== -1) {
                this.resCategories[targetItemIndex].index =
                    parseInt(this.resCategories[targetItemIndex].index) - 1;
                this.resCategories[currentItemIndex].index =
                    parseInt(this.resCategories[currentItemIndex].index) + 1;
                this.__fromatData(this.resCategories);
            }
        },
        handleSelectionChange(checkeds) {
            const that = this;
            that.courseCheckeds = [];
            if (checkeds.length === 0) return;
            _.forEach(checkeds, item => {
                if (item) {
                    if (item.pid) {
                        that.courseCheckeds.push({
                            labelId: item.pid,
                            level: item.plevel,
                            type: this.dataType
                        });
                    }
                    that.courseCheckeds.push({
                        labelId: item.id,
                        level: item.level,
                        labelType: item.labelType || 0,
                        type: this.dataType
                    });
                }
            });
            that.courseCheckeds = _.unionBy(that.courseCheckeds, "labelId");
        },
        handleLabelTypeChange(item) {
            let changeItem = _.find(this.courseCheckeds, {
                labelId: item.id
            });
            changeItem && (changeItem.labelType = item.labelType);
        }
    }
};
</script>
<style lang="scss" scoped>
.tip-message {
    margin: 10px 0;
    font-size: 14px;
    color: #909090;
}
</style>
